package com.zmkj.cn.comm.aop;


import com.zmkj.cn.comm.exception.BaseException;
import com.zmkj.cn.sys.dto.SysManagerDto;
import com.zmkj.cn.comm.util.ThreadLocalUtil;
import com.zmkj.cn.comm.vo.BaseQueryVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 伍绍宇
 */
@Aspect
@Component
@Slf4j
@Order(3)
public class ParamAop {

    /**
     * 设置切入点未restTemplete下的所有方法
     */
    @Pointcut("execution(public * com.zmkj.cn.*.controller..*.*(..))")
    public void aopController() {
    }




    @Around("aopController()")
    public Object arround(ProceedingJoinPoint pjp) {
        //获取目标方法体参数
        Object[] parames = pjp.getArgs();
        //返回公共信息
        Object o;
        try {
            for (Object parame : parames) {
                if (parame == null) {
                    continue;
                }
                if (BaseQueryVo.class.isAssignableFrom(parame.getClass())) {
                    SysManagerDto sysManagerDto = ThreadLocalUtil.getCurrentManager();
                    invokeByMethod("setDeptNo", String.class, parame, sysManagerDto.getDeptNo());
                    if (sysManagerDto.getRoleType() != null && sysManagerDto.getRoleType() != 1) {
                        invokeByMethod("setCreateUser", String.class, parame, ThreadLocalUtil.getCurrentManager().getId());
                    }
                }
            }
            o = pjp.proceed(parames);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw  new BaseException("操作异常",throwable.getMessage(),-1);
        }
        return o;
    }

    /**
     *
     * @param methodName 方法名
     * @param obj  方法参数
     * @param parma  执行对象
     * 
     */
    private Method getMethodByName(String methodName, Class obj, Object parma){
        Method objMethod=null;
        try {
            objMethod=parma.getClass().getMethod(methodName,obj);
        } catch (NoSuchMethodException e) {
            return null;
        }
        return objMethod;
    }


    /**
     * 根据方法名 执行方法
     * @param methodName 方法名
     * @param obj 参数类型
     * @param param 执行对象
     * @param value 执行值
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private void invokeByMethod(String methodName,Class obj,Object param,Object value) throws InvocationTargetException, IllegalAccessException {
        Method  invokeMethod=getMethodByName(methodName,obj,param);
        if(invokeMethod!=null){
            invokeMethod.invoke(param,value.toString());
        }
    }
}
